﻿using System;

namespace FlashPay.DAO.Impl.Report
{
    using FlashPay.DAO.Interface;
    using FlashPay.DAO.Report;
    using FlashPay.EF;
    using FlashPay.EF.Models;
    using FlashPay.Entity;
    using FlashPay.Entity.Parameter;
    using FlashPay.Entity.Response.Report;
    using Microsoft.EntityFrameworkCore;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;

    /// <summary>
    /// 报表数据接口实现
    /// </summary>
    /// <remarks>immi 创建</remarks>
    public class ReportStatisticsDaoImpl : IDisposable, ReportStatisticsDao
    {
        #region 注入
        /// <summary>
        /// EF上下文
        /// </summary>
        private FlashPayContext _context { set; get; }

        /// <summary>
        /// 公司数据接口
        /// </summary>
        private readonly CompanyDao _companyDao;

        /// <summary>
        /// 注入
        /// </summary>
        /// <param name="context">EF上下文</param>
        /// <param name="companyDao">公司</param>
        public ReportStatisticsDaoImpl(FlashPayContext context, CompanyDao companyDao)
        {
            _context = context;
            _companyDao = companyDao;
        }

        public void Dispose()
        {
            if (_context != null)
            {
                _context.Dispose();
            }
        }
        #endregion

        /// <summary>
        /// 获取所有报表
        /// </summary>
        /// <param name="query">查询条件</param>
        /// <returns>List<UserInfo></returns>
        public List<ReportStatistics> GetList(ReportStatisticsQuery query)
        {
            var where = PredicateBuilder.True<ReportStatistics>();
            //20181217 SeanLin
            //增加条件 BCID = 0 ， BCID = 0 OR != 0 都有公司ID，会重覆计算
            //where = where.And(c => c.CardBcid == 0);
            //公司编号
            if (query.CompanyId.HasValue)
            {
                where = where.And(c => c.CompanyId == query.CompanyId);
            }
            //公司编号
            if (query.CompanyIds != null && query.CompanyIds.Any())
            {
                where = where.And(c => query.CompanyIds.Contains(c.CompanyId));
            }
            //类型
            if (query.ReportType.HasValue)
            {
                where = where.And(c => c.ReportType == query.ReportType);
            }
            //银行卡编号
            if (query.BankCardIds != null && query.BankCardIds.Any())
            {
                where = where.And(c => query.BankCardIds.Contains(c.CardBcid));
            }
            //银行卡编号
            if (query.CardBcid.HasValue)
            {
                where = where.And(c => c.CardBcid == query.CardBcid);
            }
            //报表时间
            if (!string.IsNullOrEmpty(query.StartTime) && !string.IsNullOrEmpty(query.EndTime))
            {
                where = where.And(c => c.ReportDate >= Convert.ToDateTime(query.StartTime) && c.ReportDate <= Convert.ToDateTime(query.EndTime));
            }

            var payType = query.PaymentType;
            if (query.ReportType == 1) //存款
            {
                if (payType != null && payType != -1)
                {
                    where = where.And(e => e.Transtype == payType);
                }
            }
            else //付款
            {
                if (payType != null && payType != -1)
                {
                    where = where.And(e => e.PaymentType == payType);
                }
            }

            var list = _context.ReportStatistics.Where(where.Compile()).ToList();
            return list;
        }

        /// <summary>
        /// 获取公司月报表
        /// </summary>
        public List<ReportByMonthResponse> GetReportByMonth(ReportStatisticsQuery query)
        {
            //原始Sql:select date_format(ReportDate,'%d') day,SUM(ReportAmount) AS TotalAmount,SUM(ReportQuantity) AS TotalQuantity from ReportStatistics WHERE ReportType=1 AND (ReportDate>='2018-09-01 00:00:00' AND ReportDate<='2018-09-30 23:59:59') GROUP BY day

            var reportDate = Convert.ToDateTime(query.StartTime);

            var q = _context.ReportStatistics.Where(c => c.ReportType == query.ReportType && query.CompanyIds.Contains(c.CompanyId) && c.ReportDate.Year == reportDate.Year && c.ReportDate.Month == reportDate.Month);

            if (query.ReportType ==1  && query.PaymentType.HasValue)
            {
                q = q.Where(e => e.Transtype == query.PaymentType.Value);
            }
            else if(query.PaymentType.HasValue)
            {
                q = q.Where(e => e.PaymentType == query.PaymentType.Value);
            }

            var list = q.GroupBy(n => n.ReportDate.Day).Select(g => new ReportByMonthResponse
            {
                Day = g.Key,
                TotalAmount = g.Sum(x => x.ReportAmount),
                TotalQuantity = Convert.ToDecimal(g.Sum(x => x.ReportQuantity))
            });
            return list.ToList();
        }


        /// <summary>
        /// 获取公司月报表
        /// </summary>
        public List<ReportByMonthResponse> GetReportByCompanyId(ReportStatisticsQuery query)
        {

            var list = _context.ReportStatistics.Where(c => c.ReportType == query.ReportType && query.CompanyIds.Contains(c.CompanyId) && c.ReportDate >= Convert.ToDateTime(query.StartTime) && c.ReportDate <= Convert.ToDateTime(query.EndTime)).GroupBy(n => n.CompanyId).Select(g => new ReportByMonthResponse
            {
                CompanyId = g.Key,
                TotalAmount = Convert.ToDecimal(g.Sum(x => x.ReportAmount)),
                TotalQuantity = Convert.ToDecimal(g.Sum(x => x.ReportQuantity))
            });

            return list.ToList();
        }

        /// <summary>
        /// 根据银行卡编号分组 获取公司下的收、付款记录总和
        /// </summary>
        public List<ReportByMonthResponse> GetReportByCardBcId(ReportStatisticsQuery query)
        {

            var list = _context.ReportStatistics.Where(c => c.ReportType == query.ReportType && query.CompanyIds.Contains(c.CompanyId) && c.ReportDate >= Convert.ToDateTime(query.StartTime) && c.ReportDate <= Convert.ToDateTime(query.EndTime)).GroupBy(n => n.CardBcid).Select(g => new ReportByMonthResponse
            {
                CardBcid = g.Key,
                TotalAmount = g.Sum(x => x.ReportAmount),
                TotalQuantity = Convert.ToDecimal(g.Sum(x => x.ReportQuantity))
            });

            return list.ToList();
        }

        /// <summary>
        /// 获取公司年报表
        /// </summary>
        public List<ReportStatisticsNew> GetReportByYear(ReportStatisticsQuery query)
        {
            //20181217 SeanLin
            //增加条件 BCID = 0 ， BCID = 0 OR != 0 都有公司ID，会重覆计算
            //时间条件 从CreateDate 修改为 ReportDate
            int y = Convert.ToInt32(query.StartTime);
            var q = _context.ReportStatistics.Where(c=>c.ReportDate.Year == y).Where(e=> query.CompanyIds.Contains(e.CompanyId))
                .Where(e=>e.ReportType == query.ReportType);

            if (query.ReportType == 1 && query.PaymentType.HasValue)
            {
                q = q.Where(e => e.Transtype == query.PaymentType.Value);
            }
            else if (query.PaymentType.HasValue)
            {
                q = q.Where(e => e.PaymentType == query.PaymentType.Value);
            }

            var notifications = q.GroupBy(n => n.ReportDate.Month).Select(g => new ReportStatisticsNew
            {
                    Year = g.Key,
                    TotalAmount = g.Sum(x => x.ReportAmount),
                    TotalQuantity = g.Sum(x => x.ReportQuantity)
            });

            var list = notifications.ToList();

            return list;
        }

        /// <summary>
        /// 获取最后更新时间
        /// </summary>
        /// <returns></returns>
        public JResult<string> GetLastUpdateDate() {

            var result = new JResult<string>()
            {
                Success = false
            };

            var reportStatistics = _context.ReportStatistics.LastOrDefault();

            if (reportStatistics != null) {
                result.Success = true;
                result.Data =  reportStatistics.CreateDate.ToString("yyyy-MM-dd HH:mm:ss");
            }

            return result;
        }
        
    }
}
